package com.crazymakercircle.mutithread.basic.zbl;

import com.crazymakercircle.util.Print;
import org.junit.Test;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import static com.crazymakercircle.util.ThreadUtil.sleepSeconds;

/**
 * @author ：weimo
 * @date ：Created in 2025/1/12
 * @description：基于线程工厂建立线程池
 */

public class CreateThreadPoolDemo {

    static public class SimpleThreadFactory implements ThreadFactory{

        static AtomicInteger threadNo=new AtomicInteger(1);
        @Override
        public Thread newThread(Runnable r) {

            String threadName="simpleThread-"+threadNo.get();
            Print.tco("创建一条线程,名称为："+threadName);
            threadNo.incrementAndGet();
            //设置线程名称 和执行目标
            Thread thread = new Thread(r, threadName);
            thread.setDaemon(true);
            return thread;
        }

    }

    @Test
    public  void testThreadFactory(){
        //使用自定义线程工厂 创建一个固定大小的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2, new SimpleThreadFactory());

        for (int i=0;i<5;i++){
            Future<?> future = executorService.submit(new com.crazymakercircle.mutithread.basic.create3.CreateThreadPoolDemo.TargetTask());
        }

        sleepSeconds(10);
        Print.tco("关闭线程池");
        executorService.shutdown();
    }

    //线程本地变量,用于记录线程异步任务的开始执行时间
    private static final ThreadLocal<Long> START_TIME = new ThreadLocal<>();



    /**
     * 功能描述: 调度器的钩子方法
     *      任务执行之前的钩子，任务执行之后的钩子方法，线程池终止时的钩子方法。
     *      重新这些钩子方法测试
     * @auther: zhangbanglong
     * @date: 21:51
     * @param
     * @return
    */

    @Test
    public void testHooks(){

       ExecutorService pool= new ThreadPoolExecutor(2,4,60,TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(2)){
            @Override
            protected void terminated(){
                Print.tco("调度器已经终止！");
            }

            @Override
            protected  void beforeExecute(Thread t ,Runnable target){
                Print.tco(target+"执行前钩子");

                START_TIME.set(System.currentTimeMillis());
                super.beforeExecute(t,target);

            }

            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
                long time=(System.currentTimeMillis()-START_TIME.get());

                Print.tco(r+"后钩被执行，任务执行时长（ms）"+time);

                START_TIME.remove();
            }
        };

        for (int i=1;i<5;i++){
            pool.execute(new com.crazymakercircle.mutithread.basic.create3.CreateThreadPoolDemo.TargetTask());
        }

        sleepSeconds(10);
        Print.tco("关闭线程池");
        pool.shutdown();
    }



    /**
     * 功能描述: 自定义一个拒绝策略
     * @auther: zhangbanglong
     * @date: 21:56
     * @param null
     * @return
    */

    public static class CustomIgnorePolic implements RejectedExecutionHandler{

        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            //可做日志记录等
            Print.tco("into 拒绝策略方法！"+r+" rejected; "+"- getTaskCount:"+ executor.getTaskCount());
        }

        @Test
        public void testCustomIgnorePolicy(){
            int corePollSize=2;
            int maximumPoolSize=4;
            TimeUnit unit=TimeUnit.SECONDS;

            BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<>(2);
            //线程工程
            ThreadFactory threadFactory=new SimpleThreadFactory();
            //线程池的拒绝策略
            RejectedExecutionHandler policy=new CustomIgnorePolic();
            ThreadPoolExecutor pool=new ThreadPoolExecutor(corePollSize,
                    maximumPoolSize,
                    10,unit,workQueue,threadFactory,policy);

            for (int i=1;i<=10;i++){
                pool.execute(new com.crazymakercircle.mutithread.basic.create3.CreateThreadPoolDemo.TargetTask());
            }

            sleepSeconds(10);
            Print.tco("关闭线程池");
            pool.shutdown();


        }
    }
}
